/*
*    Phantom v2.0 GUI Automation Software
*    Copyright (C) 2009  John C. Van Arsdall (john@phantomtest.com)
*
*    This program is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License along
*    with this program; if not, write to the Free Software Foundation, Inc.,
*    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include "ssi_functionapi.h"
#include "ssi_engine.h"
#include "ssi_functionapi.h"

SSI_INT64 SSI_FunctionAPI::m_Version = 0;

SSI_FunctionAPI::SSI_FunctionAPI(void)
{
	Parameters = SSI_NULL;
	m_ReturnStatus = STAT_OK;
}

SSI_FunctionAPI::~SSI_FunctionAPI(void)
{
	ClearParameters();
}

SSI_INT64 SSI_FunctionAPI::GetVersion(void)
{
	return m_Version;
}

CStatus SSI_FunctionAPI::SetReturnData(CVariable* Data)
{
	RetVar = *Data;
	return STAT_OK;
}

CStatus SSI_FunctionAPI::SetReturnData(CData* Data)
{
	return RetVar.SetWorkingData(Data);
}

CVariable* SSI_FunctionAPI::operator[](SSI_INT64 Index)
{
	CVariable* aData = Parameters[Index];
	return aData;
}
CVariable* SSI_FunctionAPI::GetReturnData(void)
{
	return &RetVar;
}

void SSI_FunctionAPI::ClearParameters(void)
{
	SSI_INT64 index = 0;
	if(Parameters){
		//delete [] Parameters; // This will delete all CVariables, I guess
		while(Parameters[index]){
			CVariable* Var = Parameters[index];
			delete Var;
			//delete Parameters[index];
			Parameters[index] = 0;
			index++;
		}
	}
	delete [] Parameters;
	Parameters = 0;
		///if(Parameters){

		//theAPI.Parameters = new CVariable*[NumParams+1];  // This is just pointers

		//delete [] Parameters;
	//}
	//Parameters = SSI_NULL;

}

SSI_INT64 SSI_FunctionAPI::GetNumParams(void)
{
	SSI_INT64 Ret = 0;
	if(!Parameters) return 0;
	while(Parameters[Ret]){
		Ret++;
	}
	return Ret;
}

SSI_BOOL SSI_FunctionAPI::AddParameter(CVariable& aVar, SSI_INT64 Index)
{
	if(Index > GetNumParams()){
		return 0;
	}

	CVariable* NewVar = new CVariable(aVar);
	*Parameters[Index] = *NewVar;
	delete NewVar;
	return 1;
}

SSI_BOOL SSI_FunctionAPI::InitParams(SSI_INT64 NumParams)
{
	ClearParameters();
	SSI_INT64 ctr = 0;
	Parameters = new CVariable*[NumParams+1];  // This is just pointers
	//CVariable *Vars = 0;
	//if(NumParams > 0){
	//	Vars = new CVariable[NumParams];
	//}

	while(ctr < NumParams){
		Parameters[ctr] = new CVariable();//&Vars[ctr];
		ctr++;
	}
	Parameters[NumParams] = 0;
	return 1;
}

/* This dont work...
SSI_FunctionAPI& SSI_FunctionAPI::operator =(SSI_FunctionAPI& Other)
{
	ClearParameters();
	SetReturnData(&Other.RetVar);
	m_ReturnStatus = Other.m_ReturnStatus;
	m_Engine = Other.m_Engine;
	m_FunctionName = Other.m_FunctionName;
	m_Version = Other.m_Version;

	SSI_INT64 NumParams = Other.GetNumParams();
	SSI_INT64 ctr = 0;

	InitParams(NumParams);
	for(ctr = 0; ctr < NumParams; ctr++){
		AddParameter(*Other[ctr], ctr);
	}
	return *this;
}
*/
SSI_INT64 SSI_FunctionAPI::GetParameterType(SSI_INT64 Index)
{
	CVariable* aVar = (*this)[Index];
	if(aVar){
		return aVar->GetType();
	}else{
		return -1;
	}
}

SSI_FunctionAPI& SSI_FunctionAPI::operator =(SSI_FunctionAPI &Other)
{
	m_Engine = Other.m_Engine;
	m_FunctionName = Other.m_FunctionName;
	m_ReturnStatus = Other.m_ReturnStatus;
	m_Version = Other.m_Version;
	ClearParameters();
	Parameters = CopyParameters(Other.Parameters, Other.GetNumParams());
	RetVar = Other.RetVar;

  return *this;
}

CVariable** SSI_FunctionAPI::CopyParameters(CVariable** Others, SSI_INT64 Count)
{
	if(!Others) return 0;

	if(!InitParams(Count)){
		return 0;
	}

	SSI_INT64 index = 0;
	if(Others){
		while(Others[index]){
		//CVariable* NewVar = new CVariable(aVar);
		//Parameters[Index] = NewVar;

		AddParameter(*Others[index], index);
			//Parameters[index] = new CVariable(*Others[index]);
			//*Parameters[index] = *Others[index];
			index++;
		}
	}
	return Parameters;
}

CData* SSI_FunctionAPI::GetSingleData(SSI_INT64 I)
{
  if(I > GetNumParams()){
    return NULL;
  }else{
    return (CData*)*(*this)[I];
  }
}



